/*
基本数据类型
整型、浮点数、波尔、字符串、字符（数值类型）
整型 有符号  int8   int16  int32  int64
	无符号  uint8  uint16 uint32 uint64
范围 有符号 -2^(位数-1) - 2^(位数-1) - 1
	无符号 2^(位数)-1

查看使用字节 unsafe.Sizeof()

默认值   整型 浮点 0  byte 是数值类型没啥默认值无法'' 字符串 "" 波尔 false

字符串
转译字符
\r  换行
\n  回车  Print用这一个就行了 如果文件需要 \r\n 当然 Print也可以\r\n
\t 制表
\'
\""
\\

字符 byte rune
*/
package main

/*
字符串
*/
func str() {
	// 字符串没法用unsize.Sizeof 获取字节大小可以用len
	// 转译
	// fmt.Println("d:\\a\\b's\"\tadmin\nistor\rtra\r\nkk")

	//多行字符串
	// fmt.Print(`
	// admin
	// 123
	// 467
	// `)

	// 字符串常用函数
	// strings
	// len + fmt.Sprintf  len:长度是字节长度utf8 英文1个 中文3个字节 + Springf 拼接同fmt.Printf 只不过这个是返回格式化后的字符串
	// strings.Split 分割
	// strings.Contains 包含
	// strings.HasPrefix 前缀
	// strings.HasSuffix 后缀
	// strings.Index() 包含其实位置下标 查找不到返回-1 下标从 0 开始
	// strings.LastIndex() 从后往前找  下标从前往后 查找不到返回-1 下标从 0 开始
	// strings.Join() 拼接

	// len
	// a := len("的12a")
	// fmt.Print(a)

	// +
	// a := "a"
	// b := "b"
	// fmt.Print(a+b)

	// a := 1
	// b := 1.1
	// c := "admin"
	// d := 'a'
	// str := fmt.Sprintf("%d,%f,%v,%c", a, b, c, d)
	// fmt.Print(str)

	// str := "a,b,c"
	// fg := strings.Split(str, ",")
	// fmt.Print(fg)

	// str := "ding.luchao"
	// ok := strings.Contains(str, "lu")
	// fmt.Print(ok)

	// str := "1_admin"
	// ok := strings.HasPrefix(str, "_")
	// fmt.Print(ok)

	// str := "1_admin_"
	// ok := strings.HasSuffix(str, "_")
	// fmt.Print(ok)

	// str := "1_admin"
	// ok := strings.Index(str, "_")
	// fmt.Print(ok)

	// str := "1_admin"
	// ok := strings.LastIndex(str, "_")
	// fmt.Print(ok)

	// str := strings.Join(strings.Split("a,b,c", ","), "-")
	// fmt.Print(str)

}

/*
  字符
  byte 值类型 rune
*/
func byteRune() {
	// 定义字符用单引号 'a' 字符只有一个 字符不能定义''空的报错 值是int类型的
	// a := 'a'
	// fmt.Print(a) // 为什么说是值类型，返回的是ascii码里面的码表对应值。注意中文三个字节的。u8表对应的值
	// 如果要输出对应码表值对应的字符用%c
	// 中文需要range + rune来搞输出

	// 遍历字符串 range i:= 都以  中文3个字节 英文1个字节 中文utf8码表  英文ascii码表
	// str := "admin管理员"
	// for i := 0; i < len(str); i++ {
	// 	fmt.Printf("%v=>%c\r\n", str[i], str[i]) // 中文无法打印所以需要range + rune来搞
	// }

	// range + rune
	// str := "admin管理员"
	// for _, v := range []rune(str) {
	// 	fmt.Printf("%v=>%c\r\n", v, v)
	// }

	// 字符串没法用unsafe.Sizeof 获取大小可以用len

	// c := '国'
	// fmt.Printf("%v=>%c", c, c) // 打印utf8表对应的值和对应的符号

	// for i 相当于 byte类型

	// for range 相当于rune类型

	// byte 适合流字节

	// rune 搞中文遍历

	// 字符类型分  byte(ascii表用这个) 和 rune(utf8用在这个中文) rune 也兼容byte 更强大一些  range遍历不是每个字节个搞  是ascii的就输出ascii 是中文的就输出对应utf8表对应的值。

	// 文件流操作用byte就好

	// 修改字符串， 首先要将字符串转 　byte 或者 rune 类型 纯 ascii 的就 byte或者rune都可以，中文混合就rune来搞 无论什么修改方式都需要重新分配内存来搞。
	// str1 := []byte("admin")
	// str2 := []rune("大admin")

	// str1[0] = 'm'
	// str2[0] = '龙'

	// fmt.Println(string(str1), string(str2)) // 默认回来是切片类型的值  数值所以要转成字符串

	// 不能这么玩
	// str := "aaa"
	// str[0] = 'b'
	// fmt.Println(str)

}

/*
 类型的转换
*/
func zh() {
	// 数值类型的转换就是 xxx(被转的变量)
	// fmt.Println("zh")
	// 举例说明
	// a := 123
	// fmt.Println(float64(a))

	// 相操作注意 两边类型相同  注意低往高转

	// string的转换 strconv or fmt.Springf
	// str := fmt.Sprintf("%f", 3.22222)
	// fmt.Println(str)

	// 波尔输出是%t
	// it := 1
	// fl := 3.12
	// bl := false
	// // byte转string 直接上string()格式化

	// // 其它类型转字符串
	// itstr := strconv.FormatInt(int64(it), 10)             // 参数1要转的值 参数2 你传进来的是个什么进制
	// flstr := strconv.FormatFloat(float64(fl), 'f', 2, 64) // 参数1 要转换的值 参数2格式化输出的模版 参数3保留的小数点-1默认不格式化  参数4 你传进来的多少位
	// blStr := strconv.FormatBool(bl)

	// fmt.Println(itstr, flstr, blStr)

	// // string 转其它类型 值类型转换失败返回0 转换失败就是默认值
	// blz, _ := strconv.ParseBool(blStr) // 这个玩法没啥意义 不建议string转bool 得到不预期的结果
	// flz, _ := strconv.ParseFloat(flstr, 64) 参数1 进来的值 参数2 出去的是多少位
	// itz, _ := strconv.ParseInt(itstr, 10, 64) 参数1 进来的值 参数2 转为10进制 参数3 出来的是多少位
	// fmt.Printf("%t,%f,%d", blz, flz, itz)

	// 格式化byte类型的
	// a := 'a'
	// astr := strconv.FormatUint(uint64(a), 10)
	// fmt.Printf("%T", astr)

	// fmt.Print(strconv.ParseBool("false"))
}

/*
  预算符
*/
func ysf() {
	// 算数运算符没啥讲的就讲讲自增自减吧 注意自增自减就只能自己一行 不能赋值也不能把加号减号放前面
	// it := 0
	// it++
	// it--
	// fmt.Print(it)

	// // 两个int类型的数相除会扔掉小数 没有四舍五入
	// fmt.Println(1 / 2)

	// 注意 数值字面量可以前面小数后面整数，但是变量搞两边必须一样
	// fmt.Println(1.0 / 2)
	// fmt.Println(a / 2)

	// 余数 = 被除数 - （被除数/除数）*除数 10%3=1， -10%3 = -1，  10%-3 = 1

	// 交换
	// a := 100
	// b := 200
	// a = a + b
	// b = a - b
	// a = a - b
	// fmt.Println(a, b)
	// a := 100
	// b := 2
	// fmt.Println(a & b)]
	// a := 4  << * 2 ^ n >> / 2 ^ n
	// fmt.Println(a >> 1)
}

func main() {

	// var a int = 1
	// fmt.Printf("%T", a) // 打印 int int没有指定具体类型默认和操作系统位数有关 32 就是 int32 64位系统 int64 但是和真正的int32 64操作也需要转

	// 如果赋值超出范围溢出 小往大转

	// 打印字节大小
	// var a int // 查看占用大小
	// fmt.Print(unsafe.Sizeof(a), "===>>>")

	// 整型类型转换
	// var a int = 1
	// var b = int64(a)
	// // a + b 报错需要统一类型 建议小转大 大转小注意溢出
	// fmt.Printf("%T", b)

	// 进制输出  转10 进制   以二进制为例其他一样  1010  0 * 2^0 + 1 * 2^1 + 0 * 2^2 + 1 * 2^3
	// a := 10
	// fmt.Printf("2=%b\n", a) // 2进制
	// fmt.Printf("8=%o\n", a) // 8进制
	// fmt.Printf("8=%d\n", a) // 10进制
	// fmt.Printf("8=%x", a)   // 16进制

	// 浮点型
	// fmt.Println(math.MaxFloat32) 3.4e38
	// fmt.Println(math.MaxFloat64) 1.8e308

	// 浮点数通过%f来格式化输出 默认取6位小数  float和int一样如果没有具体位数以操作系统位数为准 32 对应 32 64 对应 64 所以下面是8个字节默认float64 四舍五入
	// fmt.Printf("%f,%v", 3.1234999999, unsafe.Sizeof(1.1))

	// %f %.2f 保留2位 四舍五入

	// float精度丢失问题
	// fmt.Println(19.9) // 1989.999999999999
	// 使用第三方库来解决
	// decimal 库 go get github.com/shopspring/decimal
	// fmt.Println(decimal.NewFromFloat(3.12)) 操作的时候全部用Newxxxx包裹起来然后通过运算函数取操作 多个操作数全部需要包裹 同样转换小转大

	// float转int 小数就直接扔了 没有四舍五入 注意别溢出
	// a := 3.999999
	// b := int(a)
	// fmt.Println(b)

	// go bool 个人觉得很鸡肋没啥用 只有 true false 和js不同 1 "" 都无法转bool 当然strconv 可转 bool 但是没啥用和预期结果也不同 默认值 false
	// bool 无法参与数值运算

	// 字符串
	// str()

	// byte rune
	//byteRune()

	// 转换
	// zh()

	// 运算符
	ysf()
}
